#coding: utf-8
try:
    from xml.etree import ElementTree
except ImportError:
    from elementtree import ElementTree
import third.gdata.spreadsheet.service
import third.gdata.service
import third.gdata.docs.service
import os
import re

class Kgdata():
    class FileNotFile(Exception):
        pass
    class WorkSheetNotFind(Exception):
        pass
    
    def __init__(self, email, password):
        self.gd_client = self._Login_gdata(email, password)
        self.curr_key = '' # self.get_Spreadsheet_File_Key(self.gd_client, file_name)
        self.curr_wksht_id = '' # self.get_wksht_id(self.gd_client, self.curr_key, wksht_name)

    def _Login_gdata(self, email, password):
        '''成功验证后返回google data的连接对像,否刚抛出异常'''
        self.gd_client = third.gdata.spreadsheet.service.SpreadsheetsService()
        self.gd_client.email = email
        self.gd_client.password = password
        self.gd_client.source = 'kingmail system'
        self.gd_client.ProgrammaticLogin()
        return self.gd_client
    #end Login_gdata()

    def set_Spreadsheet_File_Key(self, filename):
        if type(filename) == unicode:
            filename = filename.encode('utf8')
        
        q = third.gdata.service.Query ()
        q['title'] = filename
        q['title-exact'] = 'true'
        feed = self.gd_client.GetSpreadsheetsFeed(query=q)
        
        try:
            self.curr_key = feed.entry[0].id.text.split('/')[-1]
        except:
            raise Kgdata.FileNotFile('File does not exist in google server!')
#            Exception('File does not exist in google server!')
        
        return self.curr_key 
        
        
    def set_wksht_id(self, sheet_tb_name):
        if type(sheet_tb_name) == unicode:
            sheet_tb_name = sheet_tb_name.encode('utf8')
            
        q = third.gdata.service.Query ()
        q['title'] = sheet_tb_name
        q['title-exact'] = 'true'
      
        feed = self.gd_client.GetWorksheetsFeed(self.curr_key, query = q)
        
        try:
            self.curr_wksht_id = feed.entry[0].id.text.split('/')[-1]
        except:
            raise Kgdata.WorkSheetNotFind('worksheet does not exist in this file!')
        
        return self.curr_wksht_id

    def read_WorkSheet_by_list(self, gd_client, file_key, wksht_id):
        #这种方法读回来的数据可能不是左上到右下的顺序
        wksht_xml = gd_client.GetListFeed(file_key, wksht_id) # goole API,返回还是 XML 格式

        arrlist = []
        for i, entry in enumerate(wksht_xml.entry):
            l = []
            for key in entry.custom:
                if entry.custom[key].text:
                    l.append(entry.custom[key].text)
                else:
                    l.append('')
                #print ' -> %s: \t %s' % (key, entry.custom[key].text)
            print l
            arrlist.append(l)

        return arrlist
    #end readWorkSheet

    def _cells_data_format(self, CellsFeed):
        #返回一个二维list
        arrlist = []
        l = []
        nCol = 1
        nRow = 2 #从第二行第一列读起。最好保证第二行第一个元素非空
        for i, entry in enumerate(CellsFeed.entry):
            if int(entry.cell.row) == 1:
                continue
            if int(entry.cell.row) != nRow:
                nRow = int(entry.cell.row)
                arrlist.append(l)
                l = []
                nCol = 1
                while nCol < int(entry.cell.col): #防止第一列就有空元素
                    l.append('')
                    nCol += 1
                l.append(entry.content.text.decode('utf-8'))
                nCol += 1
                continue
            while nCol < int(entry.cell.col):
                l.append('')
                nCol += 1
            if int(entry.cell.col) == nCol:
                l.append(entry.content.text.decode('utf-8'))
                nCol += 1
                continue
        arrlist.append(l)
        print arrlist
        return arrlist
    #end _cells_data_format()

    def read_WorkSheet_by_Cells(self):
        '''返回一个二维的list，［0］［0］ 对就表 1行1列 的值'''
        feed = self.gd_client.GetCellsFeed(self.curr_key, self.curr_wksht_id)
        return self._cells_data_format(feed)

    #end read_WorkSheet_by_Cells()

    def read_wksht_cells_area(self, strMin_col='1', strMin_row='1', strMax_col ='20', strMax_row='20'):
        '''最大行列数必需是表格存在的行列'''
        query = third.gdata.spreadsheet.service.CellQuery()
        query['min-col'] = strMin_col
        query['min-row'] = strMin_row  #从第二行开始读。约定第一行数据无效
        query['max-col'] = strMax_col  #最多X列数据，表少于X列的表会出错
        query['max-row'] = strMax_row  #

        feed = self.gd_client.GetCellsFeed(self.curr_key, self.curr_wksht_id, query=query)
        return self._cells_data_format(feed)
    #end read_wksht_cells_area()


    def CellsUpdateAction(self, row, col, inputValue):
        entry = self.gd_client.UpdateCell(row=row, col=col, inputValue = inputValue,
                                          key = self.curr_key, wksht_id = self.curr_wksht_id)
        if isinstance(entry, third.gdata.spreadsheet.SpreadsheetsCell):
            print 'Updated!'
            return True
        else:
            return False
        
    def UploadSpreadsheet(self, file_path, file_title):
        return self.UploadFile(file_path, file_title)

    def _GetFileExtension(self, file_name):
        '''Returns the uppercase file extension for a file.
        Args:
          file_name: [string] The basename of a filename.

        Returns:
          A string containing the file extension of the file.
        '''
        match = re.search('.*\.([a-zA-Z]{3,}$)', file_name)
        if match:
            return match.group(1).upper()
        return False

    def UploadFile(self, file_path, title):
        '''Prompts that enable a user to upload a file to the Document List feed.
           return filekey'''
        gd_docs_client = third.gdata.docs.service.DocsService()
        gd_docs_client.email = self.gd_client.email
        gd_docs_client.password = self.gd_client.password
        gd_docs_client.source = self.gd_client.source
        gd_docs_client.ProgrammaticLogin()
        if not file_path:
            return None
        elif not os.path.isfile(file_path):
            print 'Not a valid file.'
            return None

        file_name = os.path.basename(file_path)
        ext = self._GetFileExtension(file_name)
        if title == '':
            title = os.path.basename(file_path)

        if not ext or ext not in third.gdata.docs.service.SUPPORTED_FILETYPES:
            print 'File type not supported. Check the file extension.'
            return None
        else:
            content_type = third.gdata.docs.service.SUPPORTED_FILETYPES[ext]

        try:
            ms = third.gdata.MediaSource(file_path=file_path, content_type=content_type)
        except IOError:
            print 'Problems reading file. Check permissions.'
            return None

        if ext in ['CSV', 'ODS', 'XLS']:
            print 'Uploading spreadsheet...'
            entry = gd_docs_client.UploadSpreadsheet(ms, title)
        elif ext in ['PPT', 'PPS']:
            print 'Uploading presentation...'
            entry = gd_docs_client.UploadPresentation(ms, title)
        elif ext in ['TXT','DOC','RTF','ODT','SXW', 'WPS']:
            print 'Uploading word processor document...'
            entry = gd_docs_client.UploadDocument(ms, title)

        if entry:
            print 'Upload successful!'
            print 'Document now accessible at:', entry.GetAlternateLink().href
            return entry.GetAlternateLink().href.split('=')[-1]
        else:
            print 'Upload error.'
    #end UploadFile()
#end class Kgdata



if __name__ == "__main__":
    pass






